package com.lanxiao.cloud.modules.oauth.domain.service.impl;

import com.lanxiao.cloud.common.core.dto.UserAgentDto;
import com.lanxiao.cloud.common.core.service.IOperatorService;
import com.lanxiao.cloud.common.mybatis.service.impl.BaseServiceImpl;
import com.lanxiao.cloud.common.core.exception.BusinessException;
import com.lanxiao.cloud.common.core.error.LoginErrorType;
import com.lanxiao.cloud.modules.oauth.domain.model.UserDetails;
import com.lanxiao.cloud.modules.oauth.domain.service.ISecurityService;
import com.lanxiao.cloud.modules.oauth.infrastructure.repository.UserAouthMapper;
import com.lanxiao.cloud.modules.oauth.domain.model.UserAuth;
import com.lanxiao.cloud.modules.oauth.domain.service.ILoginService;
import com.lanxiao.cloud.modules.oauth.infrastructure.enums.LoginType;
import com.lanxiao.cloud.user.api.UserDubboApi;
import com.lanxiao.cloud.user.api.dto.LoginInfoDubboUpdate;
import com.lanxiao.cloud.user.api.dto.UserDubboDto;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

/**
 * @author ：qiaoliang
 * @date ：2021-08-24
 */
@Service
public class AccountLoginServiceImpl extends
    BaseServiceImpl<Long,UserAouthMapper, UserAuth> implements
    ILoginService {

  private final ISecurityService securityService;
  private final IOperatorService operatorService;

  @DubboReference
  private UserDubboApi userDubboApi;

  public AccountLoginServiceImpl(
      ISecurityService securityService,
      IOperatorService operatorService) {
    this.securityService = securityService;
    this.operatorService = operatorService;
  }

  @Override
  public String login(String principal, String credentials, String ip) {
    final UserAuth userAuth = this.findByPrincipal(principal);

    BusinessException.isNull(userAuth, LoginErrorType.ACCOUNT_IS_NULL_ERROR);
    userAuth.comparison(credentials);
    final UserDubboDto userDubboDto = userDubboApi.checkLogin(userAuth.getUserId());
    final UserAgentDto<Long> userAgent = operatorService.getUserAgent();

    final String token = securityService.token(
        new UserDetails(userAuth.getUserId(), userDubboDto.getName(), userDubboDto.getPortrait(),
            this.only(), principal, userAgent.getCityName(), userAgent.getIp(),
            userAgent.getBrowser(), userAgent.getOperatingSystem())
    );
    userDubboApi.loginInfoUpdate(new LoginInfoDubboUpdate(userAuth.getUserId(), ip));

    return token;
  }

  @Override
  public LoginType only() {
    return LoginType.ACCOUNT;
  }


}
